package com.uobgroup.ews.uam.core.domain;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.springframework.beans.factory.annotation.Configurable;

@Configurable
@Entity
// @NamedQueries({ @NamedQuery(name = "Profile.findProfilesByUAMRole", query =
// "SELECT P FROM Profile P WHERE P.uamRole = :uamRole") })
public class Profile extends BaseEntity implements SecurityGroupAware {

   // public static final String QUERY_FIND_PROFILES_BY_ROLE =
   // "Profile.findProfilesByUAMRole";

   public static final String PARAM_ROLE = "uamRole";

   @NotNull
   @Size(max = 64)
   private String name;

   @Size(max = 1000)
   private String description;

   @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
   @JoinTable(name = "PROFILEROLES", joinColumns = { @JoinColumn(name = "PROFILE", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "ROLES", referencedColumnName = "id") })
   private List<UAMRole> roles;

   @OneToOne(cascade = CascadeType.PERSIST)
   private SecurityGroup securityGroup;

   @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
   @JoinTable(name = "PROFILECOMBINATIONMATRICES", joinColumns = { @JoinColumn(name = "PROFILE", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "COMBINATIONMATRICES", referencedColumnName = "id") })
   private List<CombinationMatrix> combinationMatrices;

   @OneToOne
   private AccessToStaff accessToStaff;

   @Transient
   private String accessToStaffName;

   @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
   @JoinTable(name = "PROFILESEGMENTS", joinColumns = { @JoinColumn(name = "PROFILE", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "SEGMENTS", referencedColumnName = "id") })
   private List<Reference> segments;

   public String getName() {
      return this.name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getDescription() {
      return this.description;
   }

   public void setDescription(String description) {
      this.description = description;
   }

   public List<UAMRole> getRoles() {
      return roles;
   }

   public void setRoles(List<UAMRole> roles) {
      this.roles = roles;
   }

   public List<CombinationMatrix> getCombinationMatrices() {
      return this.combinationMatrices;
   }

   public void setCombinationMatrices(List<CombinationMatrix> combinationMatrices) {
      this.combinationMatrices = combinationMatrices;
   }

   public AccessToStaff getAccessToStaff() {
      return this.accessToStaff;
   }

   public void setAccessToStaff(AccessToStaff accessToStaff) {
      this.accessToStaff = accessToStaff;
   }

   public List<Reference> getSegments() {
      return this.segments;
   }

   public void setSegments(List<Reference> segments) {
      this.segments = segments;
   }

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;

   public Long getId() {
      return this.id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public SecurityGroup getSecurityGroup() {
      return securityGroup;
   }

   public void setSecurityGroup(SecurityGroup securityGroup) {
      this.securityGroup = securityGroup;
   }

   public String getAccessToStaffName() {
      if (this.accessToStaff != null) {
         accessToStaffName = accessToStaff.getName();
      }
      else {
         accessToStaffName = null;
      }
      return accessToStaffName;
   }

   public void setAccessToStaffName(String accessToStaffName) {
      this.accessToStaffName = accessToStaffName;
   }

   @Override
   public String getSecurityGroupName() {
      return name;
   }

   @Override
   public String getParentGroupName() {
      return "profile";
   }

}